import { _decorator, AudioClip, Color, Component, director, find, log, Node, Sprite, tween, UIOpacity, UITransform, v2, v3, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

import CardFunctions from "../Common/CardFunctions";
import { GameData } from "../Data/GameData";
import { BlockType, PosType } from "../Data/GameEnum";
import Grid from "./Grid";
import SS_NodeManager from "../Manager/SS_NodeManager";
import Block from "./Block";
import CommonFunction from "../utils/CommonFunction";
import { eventTarget, GameEventData } from "../Manager/SS_GameEventManager";
import { MaterialData } from "../Config/MaterialData";
import SS_TimerManager from "../Manager/SS_TimerManager";
import GamePanel from "../UI/GamePanel";
import GameStorage from "../Data/GameStorage";
import { Consts } from "../Data/Consts";
import { bdlMgr } from "../Manager/SS_BundleManager";
import { SS_AudioManager } from '../Manager/SS_AudioManager';
import { SS_Settings } from '../Data/SS_Settings';

@ccclass('BlockGroup')
export default class BlockGroup extends Component {
        @property(Node)
        main: Node | null = null;

        // id和颜色相同
        id: number = 0;
        tetrisType: number = 0;
        x: number = 0;
        y: number = 0;
        length: number = 1;
        type: BlockType = BlockType.NORMAL;
        newPosition: Vec3;
        initPosition: Vec3;
        isDead: boolean = false;
        startPos;
        block_list: Block[] = [];
        minScale: number = 0.62;
        canMove: boolean = true;
        posType: PosType;
        angle = 0;
        time = 0;
        sibling;

        init_pos_x: number = 0;
        init_pos_y: number = 0;

        onLoad(): void {
        }

        // 初始化
        init(_x: number, _y: number, _id: number, _tetrisType: number, _posType: PosType) {
                this.id = _id;
                this.x = _x;
                this.y = _y;
                this.tetrisType = _tetrisType;
                this.posType = _posType;

                this.node.active = true;
                this.node.setScale(this.minScale, this.minScale, this.minScale);;


                this.startPos = this.node.position;
                this.init_pos_x = this.node.position.x;
                this.init_pos_y = this.node.position.y;

                this.InitBlockList();

                this.AddListener();
        }

        current = null;
        current_bg
        InitBlockList() {
                CommonFunction.SetAllChildrenAtive(this.main, false);
                this.current = this.main.children[this.tetrisType];
                this.current.active = true;
                this.current.position = v3(0, 0, 0);

                this.block_list = this.current.getComponentsInChildren(Block);

                for (let index = 0; index < this.block_list.length; index++) {
                        const block = this.block_list[index];
                        block.id = this.id;
                        block.RefreshSprite();
                }

                this.current_bg = find("bg", this.current);

                let bg = find("bg/bg", this.current);
                let frame = find("bg/frame", this.current);
                let group = find("group", this.current);
                group.active = true;

                // find("bg", this.current).active = false;

                const data = MaterialData.find(e => e.id === this.id);
                bg.getComponent(Sprite).color = new Color().fromHEX(`#${data.color_bg}`);
                frame.getComponent(Sprite).color = new Color().fromHEX(`#${data.color_frame}`);

                const 线 = find("bg/线", this.current);
                for (let index = 0; index < 线.children.length; index++) {
                        const child = 线.children[index];
                        child.getComponent(Sprite).color = Color.BLACK;
                        child.getComponent(UIOpacity).opacity = 0.28 * 255;
                }
        }

        AddListener() {
                this.node.on(Node.EventType.TOUCH_START, this.TOUCH_START, this);
                this.node.on(Node.EventType.TOUCH_MOVE, this.TOUCH_MOVE, this);
                this.node.on(Node.EventType.TOUCH_END, this.TOUCH_END, this);
                this.node.on(Node.EventType.TOUCH_CANCEL, this.TOUCH_END, this);
        }
        RemoveListener() {
                this.node.off(Node.EventType.TOUCH_START, this.TOUCH_START, this);
                this.node.off(Node.EventType.TOUCH_MOVE, this.TOUCH_MOVE, this);
                this.node.off(Node.EventType.TOUCH_END, this.TOUCH_END, this);
                this.node.off(Node.EventType.TOUCH_CANCEL, this.TOUCH_END, this);
        }
        p1
        p2
        block1;
        diffx;
        diffy;

        async TOUCH_START(t) {
                // console.log(`TOUCH_START`);

                this.sibling = this.node.getSiblingIndex();

                // this.node.zIndex = 1;
                this.node.getComponent(UITransform).priority = 1;

                this.time = new Date().getTime();

                CardFunctions.AllGridSelect(false);

                if (!this.canMove) {
                        return;
                }

                GameData.IsMouseDown = true;
                this.node.setScale(1, 1, 1);
                const location = t.getLocation();
                this.initPosition = this.node.position;
                // GameData.StartPos = location;
        }

        TOUCH_MOVE(t) {
                CardFunctions.AllGridSelect(false);

                if (!this.canMove) {
                        return;
                }

                if (GameStorage.data.guide_index === 2) {
                        return;
                }

                if (GameData.IsMouseDown === true) {
                        const delta = t.getUIDelta();

                        const position = this.node.position;
                        this.node.setPosition(position.x + delta.x, position.y + delta.y);

                        {
                                for (let index = 0; index < this.block_list.length; index++) {
                                        const block: Block = this.block_list[index];
                                        let p1 = block.node.worldPosition;
                                        let p2 = SS_NodeManager.Instance.Root_grid.getComponent(UITransform).convertToNodeSpaceAR(p1);
                                        const x_new = block.GetXByX(p2.x);
                                        const y_new = block.GetXByY(p2.y);

                                        let grid: Grid = CardFunctions.GetGrid(x_new, y_new)
                                        if (grid && grid.block === null) {
                                                grid.Select(true);
                                        }
                                }
                        }
                }
        }

        async TOUCH_END(t) {
                // console.log("TOUCH_END");

                this.node.setSiblingIndex(this.sibling);
                // this.node.zIndex = 0;
                this.node.getComponent(UITransform).priority = 0;

                if (!this.canMove) {
                        return;
                }

                let time2 = new Date().getTime();
                let diff_time = time2 - this.time;

                let diff_y = this.node.position.y - this.init_pos_y;


                if (diff_time <= 300 && diff_y <= 50) {
                        await this.转圈();
                }


                CardFunctions.AllGridSelect(false);

                GameData.IsMouseDown = false;

                {
                        this.block1 = this.block_list[0];
                        this.p1 = this.current_bg.worldPosition;
                        this.p2 = this.block1.node.worldPosition;
                        this.diffx = this.p1.x - this.p2.x;
                        this.diffy = this.p1.y - this.p2.y;
                }

                let fun_list = [];
                let isTag: boolean = true;

                for (let index = 0; index < this.block_list.length; index++) {
                        const block: Block = this.block_list[index];

                        let p1 = block.node.worldPosition;
                        let p2 = SS_NodeManager.Instance.Root_grid.getComponent(UITransform).convertToNodeSpaceAR(p1);

                        const x_new = block.GetXByX(p2.x);
                        const y_new = block.GetXByY(p2.y);

                        let grid: Grid = CardFunctions.GetGrid(x_new, y_new)
                        let stopBlock = CardFunctions.GetStopBlock(x_new, y_new)


                        if (grid && grid.block === null && !stopBlock) {
                                let fun = () => {
                                        this.y = y_new;
                                        grid.block = block;
                                        block.grid = grid;

                                        let pos1 = grid.node.worldPosition;
                                        let pos2 = block.node.parent.getComponent(UITransform).convertToNodeSpaceAR(pos1);
                                        block.node.position = pos2;
                                }
                                fun_list.push(fun);

                        }
                        else {
                                isTag = false;
                                break;
                        }
                }

                if (isTag) {
                        for (let index = 0; index < fun_list.length; index++) {
                                const fun = fun_list[index];
                                fun();
                        }

                        {
                                let p = this.block1.node.worldPosition;
                                let p2 = v3(p.x + this.diffx, p.y + this.diffy, 0);
                                this.current_bg.position = this.current_bg.parent.getComponent(UITransform).convertToNodeSpaceAR(p2);
                        }

                        this.canMove = false;
                        this.posType = PosType.方格中;

                        GameData.arrBlockGroup_M.push(this);


                        this.RemoveListener()

                        await CardFunctions.随机创建一个BlockGroup(this.x);


                        CardFunctions.创建下一个BlockGroup();


                        eventTarget.emit(GameEventData.拖拽完成);

                        bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/俄罗斯方块放入中间板上`, AudioClip).then(audio => {
                                SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
                        });

                        if (GameStorage.data.guide_index === 1) {
                                GameStorage.data.guide_index++;
                                GameStorage.saveData();

                                CardFunctions.StopGuide_1();

                                if (GameStorage.data.guide_index === 2) {
                                        CardFunctions.PlayGuide_2();
                                }
                        }
                }
                else {
                        this.node.setPosition(v3(this.init_pos_x, this.init_pos_y, this.node.position.z));
                        this.node.setScale(this.minScale, this.minScale, this.minScale);
                }
        }

        async 转圈() {
                if (GameStorage.data.guide_index === 2) {
                        GameStorage.data.guide_index++;
                        GameStorage.saveData();

                        CardFunctions.StopGuide_2();
                }

                this.angle -= 90;
                tween(this.node)
                        .to(0.2, { angle: this.angle })
                        .call(() => {
                        })
                        .start();

                // bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/旋转音效`, AudioClip).then(async (audio) => {
                //         SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
                // });

                await SS_TimerManager.AwaitTime(0.2);

                for (let index_block = 0; index_block < this.block_list.length; index_block++) {
                        const block: Block = this.block_list[index_block];
                        block.node.angle += 90;
                }
        }

        是否该结账了() {
                for (let index = 0; index < this.block_list.length; index++) {
                        const block = this.block_list[index];
                        if (block.is装填完成 === false) {
                                return false;
                        }
                }

                return true;
        }

        async 结账() {
                const i = GameData.arrBlockGroup_M.indexOf(this);
                if (i > -1) {
                        GameData.arrBlockGroup_M.splice(i, 1);
                }

                GameData.destroy_card_count += this.block_list.length;

                for (let index = 0; index < this.block_list.length; index++) {
                        const block = this.block_list[index];
                        block.grid.block = null;
                }

                let pw = this.node.worldPosition;

                tween(this.node)
                        .to(0.1, { scale: v3(0.4, 0.4, 0.4) })
                        .call(async () => {
                                CardFunctions.连击();

                                CardFunctions.CreateBomb(this.node.worldPosition).then(async (bomb) => {
                                        SS_TimerManager.Instance.scheduleOnce(() => {
                                                bomb.destroy();
                                        }, 0.4);
                                });

                                // bdlMgr.getRes<AudioClip>(Consts.BundleName.AUDIO, `sound/烟雾消散`, AudioClip).then(audio => {
                                //         SS_AudioManager.Instance.playOneShot(audio, SS_Settings.curMusicV);
                                // });

                                this.node.destroy();

                                CommonFunction.vibrateShort();
                        })
                        .start();

                await SS_TimerManager.AwaitTime(0.25);


                CardFunctions.CreateEmoji().then(async (emoji) => {
                        let p4 = emoji.parent.getComponent(UITransform).convertToNodeSpaceAR(pw);
                        emoji.position = p4;

                        let p11 = GamePanel.Instance.emoji.worldPosition;
                        let p22 = emoji.parent.getComponent(UITransform).convertToNodeSpaceAR(p11);
                        tween(emoji)
                                .by(0.2, { position: v3(30, 10, 0) })
                                .to(0.3, { position: p22 })
                                .call(async () => {
                                        emoji.destroy();

                                        tween(GamePanel.Instance.emoji)
                                                .to(0.1, { scale: v3(0.6, 0.6, 0.6) })
                                                .to(0.1, { scale: v3(1, 1, 1) })
                                                .call(async () => {
                                                })
                                                .start();

                                })
                                .start();

                        await SS_TimerManager.AwaitTime(0.5);

                        GamePanel.Instance.Refresh_progress(0.5);
                });

        }
}